package com.weixun.utils.bean;

import java.beans.PropertyDescriptor;
import java.sql.Timestamp;
import java.util.Date;

import com.weixun.utils.time.DateUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

//import com.etaoxue.api.utils.ToolUtils;
//import com.jfinal.log.Log4jLogger;
//import com.jfinal.log.Logger;
import com.jfinal.plugin.activerecord.Model;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
 * 提供Model与Bean之间属性值的复制
 * @author
 *
 * @param <T> Bean类
 * @param <M> Model类
 */
public class BaseBean<T ,M extends Model<?>> {
    private Logger log = Logger.getLogger(BaseBean.class);

    /**
     * 将Model对象的数据转移到Bean对象中<br>
     * Bean中的属性要与Model中的属性名称相同
     * @param t:Bean
     * @param m:Model
     * @return
     * @throws Exception
     */
    public T revertModel2Bean(M m,T t){
        try {
            if (t!=null && m!=null) {
                PropertyDescriptor[] propertyDess = PropertyUtils.getPropertyDescriptors(t);
                if (ArrayUtils.isNotEmpty(propertyDess)) {
                    for (PropertyDescriptor propertyDescriptor : propertyDess) {
                        String propertyName = propertyDescriptor.getName();
                        //如果Model中的属性为字符串
                        if (!propertyName.equals("class")) {
                            Class proObj = PropertyUtils.getPropertyType(t, propertyName);
                            String simpleName = proObj.getSimpleName();
                            if (StringUtils.equals(simpleName, "Integer")) {
                                try {
                                    Integer intValue = null;
                                    Object valueObj = m.get(propertyName);
                                    if (valueObj instanceof Long && valueObj!=null) {
                                        intValue = m.getLong(propertyName).intValue();
                                    }else {
                                        intValue =m.getInt(propertyName);
                                    }
                                    if (intValue!=null) {
                                        BeanUtils.setProperty(t, propertyName, intValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else if(StringUtils.equals(simpleName, "Double")){
                                try {
                                    Double dobValue = m.getDouble(propertyName);
                                    if (dobValue!=null) {
                                        BeanUtils.setProperty(t, propertyName, dobValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else if(StringUtils.equals(simpleName, "Timestamp")){
                                try {
                                    Timestamp timestamp = m.getTimestamp(propertyName);
                                    Date datValue = new Date();
                                    if (timestamp != null) {
                                        datValue = new Date(timestamp.getTime());
                                    }
                                    if (datValue!=null) {
                                        BeanUtils.setProperty(t, propertyName, datValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else if(StringUtils.equals(simpleName, "String")){
                                try {
                                    String strValue = "";
                                    if (propertyName.endsWith("Time") || propertyName.endsWith("Date")) {
                                        try {
                                            Date date = m.getDate(propertyName);
                                            strValue = DateUtil.getStringDate(date.toString());
                                        } catch (Exception e) {
                                        }
                                    }
                                    if(StringUtils.isEmpty(strValue)){
                                        strValue = m.getStr(propertyName);
                                        BeanUtils.setProperty(t, propertyName, strValue);
                                    }else {
                                        BeanUtils.setProperty(t, propertyName, strValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else if(StringUtils.equals(simpleName, "Long")){
                                try {
                                    Long longValue = m.getLong(propertyName);
                                    if(longValue!=null){
                                        BeanUtils.setProperty(t, propertyName, longValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else if(StringUtils.equals(simpleName, "Float")){
                                try {
                                    Float floatValue = m.getFloat(propertyName);
                                    if (floatValue!=null) {
                                        BeanUtils.setProperty(t, propertyName, floatValue);
                                    }
                                } catch (Exception e) {
                                    continue;
                                }
                            }else {
                                log.warn("不支持的Bean数据类型，请修改代码。");
                            }
                        }else {
                            log.warn("不支持Model的属性");
                        }
                    }
                    return t;
                }
            }
        } catch (Exception e) {
            log.error("Model to bean Exception", e);
        }
        return null;
    }

    /**
     * 将Bean中值转移到Model中
     * @param t
     * @param m
     * @return
     * @throws Exception
     */
    public M revertBean2Model(T t,M m) throws Exception{
        if(t!=null && m!=null){
            PropertyDescriptor[] proDess = PropertyUtils.getPropertyDescriptors(t);
            if (ArrayUtils.isNotEmpty(proDess)) {
                for (PropertyDescriptor pro : proDess) {
                    String propertyName = pro.getName();
                    if(!StringUtils.equals(propertyName, "class")){
                        String proValue = BeanUtils.getProperty(t, propertyName);
                        Object proObj = PropertyUtils.getProperty(t, propertyName);
                        if(proObj instanceof String){
                            m.set(propertyName, proValue);
                        }else if(proObj instanceof Integer){
                            Integer intValue = 0;
                            try {
                                intValue = Integer.parseInt(proValue);
                            } catch (NumberFormatException e) {
                                intValue = 0;
                            }
                            m.set(propertyName, intValue);
                        }else if(proObj instanceof Date){
                            if(StringUtils.isNotEmpty(proValue)){
                                Timestamp timestamp = Timestamp.valueOf(proValue);
                                m.set(propertyName, timestamp);
                            }
                        }else if( proObj instanceof Long){
                            Long lng = new Long(proValue);
                            m.set(propertyName, lng);
                        }else if(proObj instanceof Double){
                            Double dob = new Double(proValue);
                            m.set(propertyName, dob);
                        }else {
                            log.warn("无法支持的数据类型");
                        }
                    }
                }

                return m;
            }
        }
        return null;
    }
}

